using System;
using System.Collections.Generic;
using Xunit.Sdk;

namespace SubSpec
{
	internal class AssertExecutor
	{
        private readonly List<SpecificationPrimitive<Action>> _asserts;
        private readonly SpecificationPrimitive<ContextDelegate> _context;
        private readonly SpecificationPrimitive<Action> _do;

        public AssertExecutor(SpecificationPrimitive<ContextDelegate> context, SpecificationPrimitive<Action> @do,  List<SpecificationPrimitive<Action>> asserts )
        {
            _asserts = asserts;
            _context = context;
            _do = @do;
        }

		public IEnumerable<ITestCommand> AssertCommands(string name, IMethodInfo method)
		{
			foreach (var assertion in _asserts)
			{
				// do not capture the iteration variable because 
				// all tests would point to the same assertion
				var capturableAssertion = assertion;
				Action test =
					() =>
					{
						using (_context.Execute())
						{
                            if (_do != null)
                                _do.Execute();

                            capturableAssertion.Execute();
						}
					};

				string testDescription = String.Format("{0}, {1}", name, assertion.Message);

				yield return new ActionTestCommand(method, testDescription, MethodUtility.GetTimeoutParameter(method), test);
			}
		}
	}
}